package org.colafries.admin.controller;

import cn.hutool.core.codec.Base64Decoder;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.colafries.admin.entity.domain.DataModel;
import org.colafries.admin.entity.vo.*;
import org.colafries.admin.exceptions.ServiceException;
import org.colafries.admin.exceptions.enums.ErrorCodeEnum;
import org.colafries.admin.service.IDataModelService;
import org.colafries.admin.wrapper.Response;
import org.colafries.admin.wrapper.ResponseWrapper;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.nio.charset.StandardCharsets;
import java.util.List;


/**
 * @author colafries
 * @version v1.0
 * @ClassName ModelController
 * @Description
 * @date Created in 2024/3/14
 **/
@RestController
@RequestMapping("/dataModel")
@Slf4j
public class DataModelController {
    @Resource
    IDataModelService iDataModelService;

    /**
     * 查询数据模型
     *
     * @param dataModelReqVO
     * @return
     */
    @PostMapping("/getAll")
    public Response getAll(@RequestBody DataModelReqVO dataModelReqVO) {
        try {
            List<DataModel> models = iDataModelService.getAll(dataModelReqVO);
            return ResponseWrapper.ok(models);
        }catch (Exception e){
            log.error("查询数据模型 接口失败 失败原因 {}", e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(), e.getMessage());
        }
    }

    /**
     * 查询数据模型列表（分页）
     * @param dataModelReqVO 模型请求vo
     * @author colafries
     * @Date 2024/3/26
     */
    @PostMapping("/getPageList")
    public Response getPageList(@RequestBody DataModelReqVO dataModelReqVO) {
        try {
            IPage<DataModel> pageData = iDataModelService.getPageList(dataModelReqVO);
            return ResponseWrapper.ok(pageData);
        }catch (Exception e){
            log.error("查询数据模型列表（分页） 接口失败 失败原因 {}", e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(), e.getMessage());
        }
    }

    /***
     * 根据id查询模型
     * @param dataModelReqVO 模型请求vo
     * @author colafries
     * @Date 2024/3/26
     */
    @PostMapping("/getById")
    public Response getById(@RequestBody DataModelReqVO dataModelReqVO) {
        try {
            DataModel dataModel = iDataModelService.getModelById(dataModelReqVO.getModelId());
            return ResponseWrapper.ok(dataModel);
        }catch (Exception e){
            log.error("根据id查询模型 接口失败 失败原因 {}", e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(), e.getMessage());
        }

    }

    /**
     * 保存或更新模型
     * @param dataModelReqVO 模型请求vo
     * @return org..common.tools.wrapper.Response
     * @author colafries
     * @Date 2024/3/22
     */
    @PostMapping("/saveOrUpdate")
    public Response saveOrUpdate(@RequestBody DataModelReqVO dataModelReqVO) {
        try {
            String decodeSql = Base64Decoder.decodeStr(dataModelReqVO.getCustomSql(), StandardCharsets.UTF_8);
            dataModelReqVO.setCustomSql(decodeSql);
            iDataModelService.saveOrUpdate(dataModelReqVO);
            return ResponseWrapper.ok();
        }catch (Exception e){
            log.error("保存模型 接口失败 失败原因 {}", e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(), e.getMessage());
        }

    }

    /**
     * 根据id删除模型
     * @param dataModelReqVO 模型请求vo
     * @return org..common.tools.wrapper.Response
     * @author colafries
     * @Date 2024/3/23
     */
    @PostMapping("/deleteByIds")
    public Response deleteByIds(@RequestBody DataModelReqVO dataModelReqVO) {
        log.info("删除模型 接口开始 入参 {}", dataModelReqVO);
        try {
            int result = iDataModelService.deleteByIds(dataModelReqVO);
            return ResponseWrapper.ok(result);
        } catch (Exception e) {
            log.error("删除模型 接口失败 失败原因 {}", e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(), e.getMessage());
        }
    }

    /**
     * 复制模型
     * @param dataModelReqVO
     * @return org.colafries.admin.wrapper.Response
     * @Author anning
     * @Date 2024/8/29
     */
    @PostMapping("/copyModel")
    public Response copyMode(@RequestBody DataModelReqVO dataModelReqVO){
        try {
            iDataModelService.copyModel(dataModelReqVO);
            return ResponseWrapper.ok();
        }catch (Exception e){
            log.error("复制模型 接口失败 失败原因 {}", e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(), e.getMessage());
        }

    }

    /**
     * 导出模型
     * @return org.colafries.admin.wrapper.Response
     * @Author anning
     * @Date 2024/8/29
     */
    @PostMapping("/export")
    public Response exportModel(@RequestBody DataModelReqVO dataModelReqVO, HttpServletResponse response) {
        log.info("导出模型 接口开始 参数 {}", JSONObject.toJSONString(dataModelReqVO));
        try {
            iDataModelService.exportModel(dataModelReqVO);
            String jsonString = JSONObject.toJSONString(dataModelReqVO);
            response.setContentType("application/json;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=model.json");
            response.getWriter().write(jsonString);
        } catch (Exception e) {
            log.error("导出模型 接口失败 失败原因 {}", e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(), e.getMessage());
        }
        return null;
    }

    /**
     * 导入模型
     * @param file
     * @return org.colafries.admin.wrapper.Response
     * @Author anning
     * @Date 2024/8/29
     */
    @PostMapping("/import")
    public Response importModel (@RequestParam("file") MultipartFile file){
        log.info("导出模型接口 开始 ");
        try {
            String jsonString = new String(file.getBytes());
            DataModelReqVO dataModelReqVO = JSONArray.parseObject(jsonString, DataModelReqVO.class);
            iDataModelService.importModel(dataModelReqVO);
            return ResponseWrapper.ok();
        }catch (Exception e){
            log.error("导入模型 失败 失败原因 {}",e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(),e.getMessage());
        }
    }

    /**
     * 查询模型配置
     * @param modelConfigReqVO 模型请求vo
     * @return org..common.tools.wrapper.Response
     * @author colafries
     * @Date 2024/3/26
     */
    @PostMapping("/getModelConfig")
    public Response getModelConfig(@Valid @RequestBody DataModelConfigReqVO modelConfigReqVO){
        try {
            List<DataModelConfigRspVO> result = iDataModelService.getModelConfig(modelConfigReqVO);
            return ResponseWrapper.ok(result);
        } catch (Exception e) {
            log.error("查询模型配置 失败 失败原因 {}", e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(), e.getMessage());
        }
    }

    /**
     * 查询模型表结构信息
     * 包括：物理表、自定义表
     * @param customTableReqVO
     * @return org..common.tools.wrapper.Response
     * @author colafries
     * @Date 2024/4/10
     */
    @PostMapping("/getTableSchema")
    public Response getTableSchema(@RequestBody CustomTableReqVO customTableReqVO){
        try {
            List<ColumnRspVO> result = iDataModelService.getTableSchema(customTableReqVO);
            return ResponseWrapper.ok(result);
        } catch (ServiceException e) {
            return ResponseWrapper.resp(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error("查询模型表结构信息 失败 失败原因 {}", e.getMessage());
            return ResponseWrapper.resp(ErrorCodeEnum.GL999999.code(), e.getMessage());
        }
    }
}
